﻿/******************************************************************************
 *  Author：       Commscope ITDC Suzhou Web Team 
 *  CreateDate：   21/02/2012 2:27:07 PM
 *
 *
 ******************************************************************************/
using System;
using System.Collections.Generic;
using System.IO;
using System.Net.Mail;
using System.Net.Mime;
using System.Text;

namespace EasyDLL.Net
{
    /// <summary>
    /// 邮件包装类
    /// </summary>
    public class MailWrapper
    {
        #region - 变量 -

        private MailMessage mailMessage = new MailMessage();
        private SmtpClient smtpClient = new SmtpClient();
        private MailAddressCollection toAddressCollection = new MailAddressCollection();
        private MailAddressCollection ccAddressCollection = new MailAddressCollection();

        #endregion

        #region - 属性 -

        /// <summary>
        /// smtp服务器地址，如果不指定则默认为smtp+发送邮件地址@后面的地址
        /// </summary>
        public string SmtpHostAddress { get; set; }

        /// <summary>
        /// 接受邮件地址的集合
        /// </summary>
        public MailAddressCollection ToAddressCollection
        {
            get { return toAddressCollection; }
            set { toAddressCollection = value; }
        }

        /// <summary>
        /// 抄送邮件地址的集合
        /// </summary>
        public MailAddressCollection CcAddressCollection
        {
            get { return ccAddressCollection; }
            set { ccAddressCollection = value; }
        }

        /// <summary>
        ///  邮件标题
        /// </summary>
        public string MailTitle { get; set; }

        /// <summary>
        /// 邮件内容
        /// </summary>
        public string MailBody { get; set; }

        /// <summary>
        /// 发送服务器认证需要的密码
        /// </summary>
        public string Password { get; set; }

        /// <summary>
        /// 发送方邮件地址
        /// </summary>
        public string FromAddress { get; set; }

        #endregion

        #region - 事件 -

        public event EventHandler<ExceptionEventArgs> SendFailureEvent;

        /// <summary>
        /// 发送邮件失败时触发
        /// </summary>
        /// <param name="e"></param>
        public void OnSendFailureEvent(ExceptionEventArgs e)
        {
            EventHandler<ExceptionEventArgs> handler = SendFailureEvent;
            if (handler != null) handler(this, e);
        }

        #endregion

        #region - 构造函数 -


        /// <summary>  
        /// 
        /// </summary>  
        /// <param name="to">收件人地址</param>  
        /// <param name="from">发件人地址</param>  
        /// <param name="body">邮件正文</param>  
        /// <param name="title">邮件的主题</param>  
        /// <param name="password">发件人密码</param>  
        public MailWrapper(string from, string to, string title, string body, string password)
        {
            FromAddress = from;
            ToAddressCollection.Add(to);
            MailBody = body;
            MailTitle = title;
            this.Password = password;
        }

        /// <summary>  
        ///  
        /// </summary>  
        /// <param name="to">收件人地址</param>  
        /// <param name="from">发件人地址</param>  
        /// <param name="body">邮件正文</param>  
        /// <param name="title">邮件的主题</param>  
        public MailWrapper(string from, string to, string title, string body)
        {
            FromAddress = from;
            ToAddressCollection.Add(to);
            MailBody = body;
            MailTitle = title;
        }

        /// <summary>  
        ///  
        /// </summary>  
        /// <param name="from">发件人地址</param>  
        /// <param name="body">邮件正文</param>  
        /// <param name="title">邮件的主题</param>  
        public MailWrapper(string from, string title, string body)
        {
            FromAddress = from;
            MailBody = body;
            MailTitle = title;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="from">发件人地址</param>
        public MailWrapper(string from)
        {
            FromAddress = from;
        }



        public MailWrapper()
        {
        }

        #endregion

        #region - 方法 -

        /// <summary>  
        /// 添加附件  
        /// </summary>  
        public void AddAttachments(List<string> paths)
        {
            for (int i = 0; i < paths.Count; i++)
            {
                AddAttachments(paths[i]);
            }
        }

        /// <summary>
        /// 添加附件
        /// </summary>
        /// <param name="path">附件路径</param>
        public void AddAttachments(string path)
        {
            Attachment data = new Attachment(path, MediaTypeNames.Application.Octet);
            ContentDisposition disposition = data.ContentDisposition;
            disposition.CreationDate = System.IO.File.GetCreationTime(path);//获取 附件的创建日期  
            disposition.ModificationDate = System.IO.File.GetLastWriteTime(path);// 获取附件的修改日期  
            disposition.ReadDate = System.IO.File.GetLastAccessTime(path);//获取附 件的读取日期  
            mailMessage.Attachments.Add(data);//添加到附件中  
        }

        /// <summary>
        /// 添加附件
        /// </summary>
        /// <param name="contentStream">附件流，请确保传入的流不是关闭的，否则可能邮件发送失败。其中一个解决不是关闭的流的方法是从原来基础上新建一个流</param>
        /// <param name="fileName">附件名字，包括后缀</param>
        /// <param name="mediaType">MediaTypeNames.Application下面的枚举</param>
        public void AddAttachments(Stream contentStream, string fileName, string mediaType)
        {
            Attachment data = new Attachment(contentStream, fileName, mediaType);
            mailMessage.Attachments.Add(data);//添加到附件中
        }



        /// <summary>  
        /// 异步发送邮件
        /// 如果要在web环境下异步发送需要将也属性asyc设置为true，另外需要
        /// 说明的是在web环境下的异步并不是立即返回给用户，而是需要等到执行完成后
        /// 再返回。所以看起来不管异步与否，用户等待的时间都是相同的。
        /// </summary>  
        /// <param name="completedMethod"></param>  
        public bool SendAsync(SendCompletedEventHandler completedMethod)
        {
            InitialMailMessage();

            if (!string.IsNullOrEmpty(Password))
            {
                smtpClient.Credentials = new System.Net.NetworkCredential(mailMessage.From.Address, Password); //设置发件人身份的票据                  
            }

            //如果smtp服务器地址没有指定则默认截取发送方的smtp地址
            if (string.IsNullOrEmpty(SmtpHostAddress))
            {
                SmtpHostAddress = "smtp." + FromAddress.Substring(FromAddress.LastIndexOf('@') + 1);
            }
            smtpClient.Host = SmtpHostAddress;
            smtpClient.SendCompleted += completedMethod;    //注册异步发送邮件完成时的事件  
            smtpClient.DeliveryMethod = SmtpDeliveryMethod.Network;

            try
            {
                smtpClient.SendAsync(mailMessage, mailMessage.Body);
                return true;
            }
            catch (Exception e)
            {
                OnSendFailureEvent(new ExceptionEventArgs(e));
                return false;
            }

        }

        //public bool SendAsyncOnWeb()
        //{
        //    ThreadPool.QueueUserWorkItem(new WaitCallback());
        //}

        /// <summary>  
        /// 发送邮件  
        /// </summary>  
        public bool Send()
        {
            InitialMailMessage();

            if (!string.IsNullOrEmpty(Password))
            {
                smtpClient.Credentials = new System.Net.NetworkCredential(mailMessage.From.Address, Password); //设置发件人身份的票据                  
            }

            smtpClient.DeliveryMethod = SmtpDeliveryMethod.Network;

            //如果smtp服务器地址没有指定则默认截取发送方的smtp地址
            if (string.IsNullOrEmpty(SmtpHostAddress))
            {
                SmtpHostAddress = "smtp." + FromAddress.Substring(FromAddress.LastIndexOf('@') + 1);
            }
            smtpClient.Host = SmtpHostAddress;

            try
            {
                smtpClient.Send(mailMessage);
                return true;
            }
            catch (Exception e)
            {
                OnSendFailureEvent(new ExceptionEventArgs(e));
                return false;
                //throw new ArgumentException("发送失败:" + e.Message);
            }
        }

        /// <summary>
        /// 初始化邮件设置（发送方，接收方，内容，标题等等）
        /// </summary>
        private void InitialMailMessage()
        {
            if (ToAddressCollection.Count <= 0)
            {
                throw new ArgumentException("发送失败");
            }

            foreach (MailAddress address in ToAddressCollection)
            {
                mailMessage.To.Add(address);
            }
            foreach (MailAddress address in CcAddressCollection)
            {
                mailMessage.CC.Add(address);
            }
            mailMessage.From = new MailAddress(FromAddress);
            mailMessage.Subject = MailTitle;
            mailMessage.Body = MailBody;
            mailMessage.IsBodyHtml = true;
            mailMessage.BodyEncoding = Encoding.UTF8;
            mailMessage.Priority = MailPriority.Normal;
        }

        #endregion
    }

}
